/* ----------------------------------------------------------------------------------------------------------------
 * PathMotion
 * ----------------------------------------------------------------------------------------------------------------
 */
package pure.engine.status.motion 
{
	import flash.geom.Point;
	import pure.engine.core.ITickListener;
	import pure.engine.model.Entity;
	import pure.engine.status.Status;

	/**
	 * 路径运动
	 * @author Pure
	 */
public class PathMotion extends Status
{
	public function PathMotion(velocity:Number, ignoreAngle:Boolean = false ) {
		this.velocity = velocity;
		_ignoreAngle = ignoreAngle;
	}
	
	
	// ----------------------------------［ Model ］----------------------------------

	protected var _ignoreAngle:Boolean;    // 是否忽略角度
	protected var _pathData:Array; // 移动路径(Point)
	protected var _velocity:Number; // 寻路速度(pixel每ms)

	protected var _walking:Boolean = false; // 是否正在移动

	protected var _pathNodeIndex:int; // 路径节点索引
	protected var _loop:int;
	protected var ____onArrive:Function; // 到达终点回调
	
	// ----------------------------------［ Cache ］----------------------------------
	
	protected var _nextNodeTotal:int; // 到达时间(ms)
	protected var _nextNodeCount:int; // 已走时间(ms)
	protected var _nextPoint:Point; // 下一抵达点
	protected var _oldX:Number; // 上一抵达点X
	protected var _oldY:Number; // 下一抵达点Y
	protected var _distX:Number; // x轴两路点间距离
	protected var _distY:Number; // y轴两路点间距离
	
	
	
	/**
	 * 寻路
	 * @param pathData      路径数据
	 * @param loop         ［<=-1:单程］［0:无限循环］［1+:循环次数］
	 */
	public function followPath(pathData:Array, loop:int = -1 , onArrive:Function = null ):void {
		this._loop = loop;
		
		// 单程
		if (_loop < 0) {
			this._pathData = pathData;
		}
		
		// 有限循环
		else if (_loop > 0) {
			this._pathData = [ ];
			// 起始路径点
			this._pathData.push(pathData[0]);
			var len:int = pathData.length;
			for (var i:int = 0; i < _loop; i++) {
				for (var j:int = 1; j < len; j++) {
					this._pathData.push(pathData[j]);
				}
				for (j = len - 2; j >= 0; j--) {
					this._pathData.push(pathData[j]);
				}
			}
		}
		
		// 无限循环
		else {
			
		}
		
		this._pathNodeIndex = 0;
		if (!_pathData || _pathData.length == 0) {
			this.walking = false;
			return;
		}
		_advanceNextNode();
		____onArrive = onArrive;
		this.walking = true;
	}
		
	/**
	 * 中止寻路
	 * @param destroyPath	毁灭路径
	 */
	public function stopFollowingPath(destroyPath:Boolean=false):void {
		this.walking = false;
		if (destroyPath && _pathData) {
			_pathData = null;
		}
	}
	
	/**
	 * 巡逻
	 */
	public function patrol(position:Point, loop:Boolean):void {
		
	}

	override public function update(deltaTime:Number):void 
	{
		if (!_walking || !_entity ) return;
		
		// 进入下一个路点
		if (this._nextNodeCount >= this._nextNodeTotal) {
			_entity.move(this._nextPoint.x, this._nextPoint.y);
			
			// 有限循环
			if (_loop != 0 ) {
				_pathNodeIndex++;
				if (_pathNodeIndex > _pathData.length - 1) {
					stopFollowingPath(true);
					if (____onArrive != null)____onArrive();
					return;
				}
			}
			// 无限循环
			else if (_loop == 0) {
				
			}

			// 更新路点
			_advanceNextNode();
		}
		else {
			var ratio:Number = this._nextNodeCount / this._nextNodeTotal;
			_entity.x = this._oldX + this._distX * ratio;
			_entity.y = this._oldY + this._distY * ratio;
		}
		this._nextNodeCount += elapsedT;
	}
	
	
	
	
	/* ----------------------------------------------------------------------------------------------------------------
	 * ★★★★★★★★★★★★★★★★★★★★★  get × set  ★★★★★★★★★★★★★★★★★★★★★
	 * ----------------------------------------------------------------------------------------------------------------
	 */
	

	 
	 
	// 寻路速度
	public function get velocity():Number { return _velocity; }
	public function set velocity(value:Number):void { _velocity = value / 1000.0; }

	// 是否正在寻路
	public function get walking():Boolean { return _walking; }
	public function set walking(b:Boolean):void {
		if (_walking == b ) return;
		_walking = b;
	}
	 
	 
	 
	
	/* ----------------------------------------------------------------------------------------------------------------
	 * ★★★★★★★★★★★★★★★★★★★★★  private  ★★★★★★★★★★★★★★★★★★★★★
	 * ----------------------------------------------------------------------------------------------------------------
	 */
	
	
	 
	 
	/**
	 * 更新下一路点
	 */
	protected function _advanceNextNode():void {
		this._nextPoint = _pathData[_pathNodeIndex];
		this._distX = _nextPoint.x - _entity.x;
		this._distY = _nextPoint.y - _entity.y;
		var dist:Number = Math.sqrt(_distX * _distX + _distY * _distY);
		this._oldX = _entity.x;
		this._oldY = _entity.y;
		
		// 到达下一路点预定时间
		this._nextNodeTotal = dist / this._velocity;
		this._nextNodeCount = 0;
		
		// 计算角度(由于移动判断与角度不相关，角度只影响section动画效果)
		if (!this._ignoreAngle) {
			var angle:Number = Math.atan2(_distY, _distX) * 180 / Math.PI + 90;
			//_owner.facing = angle < 0?360 + angle:angle;
		}
	}
	
	
	override protected function _exit():void {
		_pathData = null;
		____onArrive = null;
	}
	
}

}